#pragma once

#include <string>
#include <vector>
#include <sstream>
#include <unordered_map>

#include "common.hpp"

using namespace std;

const string default_blank_line = "\r\n"; // 默认空行

const string default_request_line_sep = " "; // 默认请求(响应)行之间的分割符

const string default_request_header_sep = "\r\n"; // 默认报头之间的分割符，以及请求行(响应)和请求(响应)报头之间的分隔符

const string defalut_key_val_sep = ": "; // 默认的HTTP报头的key和val之间的分割符

const string defalut_web_root = "./www.root"; // 默认的web根目录

const string defalut_homepage_file = "index.html"; // 默认的web根目录

const string defalut_notFound_page_path = defalut_web_root + "/NotFound.html"; // 默认的web根目录

const string defalut_URL_path_options_sep = "?"; // 默认的URL中资源路径与选项的分隔符

class HttpRequest
{

public:
    HttpRequest()
        : _blank_line(default_blank_line)
    {
    }
    void Serialization(string &out) const // 序列化
    {
        stringstream ss;
        // 请求行
        ss << _requ_method << default_request_line_sep << _url << default_request_line_sep << _version << default_request_header_sep;

        // 请求报头
        for (const auto &e : _masthead)
        {
            string tmp = e.first + defalut_key_val_sep + e.second;
            ss << tmp << default_request_header_sep;
        }

        // 空行
        ss << _blank_line;

        // 请求正文
        ss << _body;

        out = ss.str();
    }
    void Deserialization(const string &in) // 反序列化
    {
        LOG(LogLevel::DEBUG) << "进入HttpRequest: Deserialization(反序列化)";

        stringstream ss(in);

        ss >> _requ_method;
        ss >> _url;
        ss >> _version;

        string BlankLine;
        string options;

        // 去除空行
        getline(ss, BlankLine);
        while (getline(ss, options))
        {
            string key;
            string val;

            if (!Partition(options, defalut_key_val_sep, key, val))
            {
                // 如果读取到空行，就说明请求报头读取完成了
                break;
            }
            cout << "---------------------------------------" << endl;
            cout << "key: " << key << "  val: " << val << endl;
            cout << "---------------------------------------" << endl;

            // 添加报头字段
            _masthead.insert({key, val});
        }
        ss >> _body;
    }
    string Url() const
    {
        return _url;
    }
    string RequMethod() const
    {
        return _requ_method;
    }
    string version() const
    {
        return _version;
    }
    string Body() const
    {
        return _body;
    }

    string &operator[](const string &key)
    {
        return _masthead[key];
    }
    void Print()
    {
        LOG(LogLevel::DEBUG) << "打印HttpRequest: ";

        cout << _requ_method << " " << _url << " " << _version << "\r\n";

        for (const auto &e : _masthead)
        {
            string tmp = e.first + defalut_key_val_sep + e.second;
            cout << tmp << endl;
        }
        cout << endl;

        cout << _body;
    }

private:
    string _requ_method; // 请求方法
    string _url;         // 请求的资源的路径
    string _version;     // HTTP协议版本

    unordered_map<string, string> _masthead; // 响应报头

    string _blank_line; // 空行

    string _body; // 请求正文
};

class HttpResponse
{
public:
    HttpResponse()
        : _blank_line(default_blank_line)
    {
    }
    void Serialization(string &out) // 序列化
    {
        LOG(LogLevel::DEBUG) << "进入HttpResponse: Serialization(序列化)";

        stringstream ss;
        // 响应行
        ss << _version << default_request_line_sep << _status_code << default_request_line_sep << _status_code_description << default_request_header_sep;

        // 响应报头
        // 请求报头
        for (const auto &e : _masthead)
        {
            string tmp = e.first + defalut_key_val_sep + e.second;
            ss << tmp << default_request_header_sep;
        }

        // 空行
        ss << _blank_line;

        // 响应正文
        ss << _body;

        out = ss.str();
    }
    void Deserialization(const string &in) // 反序列化
    {
        LOG(LogLevel::DEBUG) << "进入HttpRequest: Deserialization(反序列化)";

        stringstream ss(in);

        ss >> _version;
        ss >> _status_code;
        ss >> _status_code_description;

        string BlankLine;
        string options;

        // 去除空行
        getline(ss, BlankLine);
        while (getline(ss, options))
        {
            string key;
            string val;

            if (!Partition(options, defalut_key_val_sep, key, val))
            {
                // 如果读取到空行，就说明请求报头读取完成了
                break;
            }
            cout << "---------------------------------------" << endl;
            cout << "key: " << key << "  val: " << val << endl;
            cout << "---------------------------------------" << endl;

            // 添加报头字段
            _masthead.insert({key, val});
        }

        ss >> _body;
    }
    void SetVersion(const string &v)
    {
        _version = v;
    }
    void SetStatusCode(const int n)
    {
        _status_code = n;
    }
    void SetStatusCodeDescription(const string &s)
    {
        _status_code_description = s;
    }
    void SetBody(const string &b)
    {
        _body = b;
    }
    string &operator[](const string &key)
    {
        return _masthead[key];
    }
    void Print()
    {
        LOG(LogLevel::DEBUG) << "打印HttpResponse: ";

        cout << _version << " " << _status_code << " " << _status_code_description << "\r\n";

        for (const auto &e : _masthead)
        {
            string tmp = e.first + defalut_key_val_sep + e.second;
            cout << tmp << endl;
        }
        cout << endl;

        cout << _body;
    }

private:
    string _version;                 // HTTP协议版本
    int _status_code;                // 状态码
    string _status_code_description; //  状态码描述

    unordered_map<string, string> _masthead; // 方便使用的响应报头

    string _blank_line; // 空行

    string _body; // 响应正文
};